home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1998 January / Macworld (1998-01).dmg / Shareware World / Comms & Internet / HTML mode 2.0 etc. / frontierMenu.tcl < prev    next >
Text File  |  1997-09-22  |  22KB  |  781 lines

  1. ## -*-Tcl-*-
  2.  # ###################################################################
  3.  #  Frontier menu - tools for using Alpha as Frontier's external editor
  4.  # 
  5.  #  FILE: "frontierMenu.tcl"
  6.  #                                    created: 97-04-03 22.01.22 
  7.  #                                last update: 97-09-06 18.02.43 
  8.  #  Author: Johan Linde
  9.  #  E-mail: <jl@theophys.kth.se>
  10.  #     www: <http://bach.theophys.kth.se/~jl/Alpha.html>
  11.  #  
  12.  # Version: 2.0
  13.  # 
  14.  # Copyright 1997 by Johan Linde
  15.  #  
  16.  # Much of the tcl code and the Frontier scripts have been written by 
  17.  # Danis Georgiadis <dmg@hyper.gr>
  18.  # 
  19.  # This software may be used freely, and distributed freely, as long as the 
  20.  # receiver is not obligated in any way by receiving it.
  21.  #  
  22.  # If you make improvements to this file, please share them!
  23.  # 
  24.  # ###################################################################
  25.  ##
  26.  
  27.  
  28. if $startingUp {
  29.     # Use the Frontier menu icon for Alpha 6.51 and above, otherwise call the menu "Frontier".
  30.     regexp {([0-9]+\.[0-9]+)[ab]?([0-9]*)} [version] dummy __vers __beta
  31.     if {$__vers < 6.51 || $__vers == 6.51 && $__beta != ""} {
  32.         set frontierMenu Frontier
  33.     } else {
  34.         set frontierMenu "•142"
  35.     }
  36.     addMenu frontierMenu
  37.     catch {unset __vers __beta}
  38.     set frontierScriptMenu Scripts
  39. #     set frontierScriptMenu •144
  40.     return
  41. }
  42.  
  43. proc frontierMenu {} {}
  44.  
  45. # ◊◊◊◊ Change below for new system §14 ◊◊◊◊ #
  46.  
  47. # Preferences
  48. newModeVar Fron autoLaunch 0 1
  49. newModeVar Fron BrowsePoints {{root root} {Websites user.websites}} 0
  50. newModeVar Fron OpenPoints {{Websites user.websites} {Glossary user.html.glossary} {Templates user.html.templates}} 0
  51.  
  52. # ◊◊◊◊ end changing for new system §14 ◊◊◊◊ #
  53.  
  54. proc frontierBrowseMenu {} {
  55.     global FronmodeVars
  56.     set bl {}
  57.     foreach b $FronmodeVars(BrowsePoints) {
  58.         lappend bl [lindex $b 0]
  59.     }
  60.     return [list menu -n Browse -p frontierMenuProc -m [concat $bl [list "(-" "Browse at…" Add… Remove…]]]
  61. }
  62.  
  63. proc frontierOpenMenu {} {
  64.     global FronmodeVars
  65.     set bl {}
  66.     foreach b $FronmodeVars(OpenPoints) {
  67.         lappend bl [lindex $b 0]
  68.     }
  69.     return [list menu -n Open -p frontierMenuProc -m [concat $bl [list "(-" "Open…" Add… Remove…]]]
  70. }
  71.  
  72. # Menu definition
  73. menu -n $frontierMenu -p frontierMenuProc -m [list \
  74.     "<U<O/FSwitch to Frontier" \
  75.     "<U<O/'View in Browser" \
  76.     "<I<O/YFrontier Shell" \
  77.     [frontierBrowseMenu] \
  78.     [frontierOpenMenu] \
  79.     "Rebuild Scripts Menu" \
  80.     Preferences…]
  81.  
  82. proc frontierMenuProc {menu item} {
  83.     global frontierMenu FronmodeVars
  84.     switch -glob $menu {
  85.         •* {
  86.             switch $item {
  87.                 "Switch to Frontier" {launchForeAppl 'LAND'}
  88.                 Preferences {FronmodifyFlags}
  89.                 default {eval frontier[join $item ""]}
  90.             }
  91.         }
  92.         Browse {
  93.             switch $item {
  94.                 "Browse at" {frontierBrowseAt}
  95.                 Add {frontierAddPoint Browse}
  96.                 Remove {frontierRemovePoint Browse}
  97.                 default {
  98.                     foreach b $FronmodeVars(BrowsePoints) {
  99.                         if {[lindex $b 0] == $item} {
  100.                             odbBrowse [lindex $b 1]
  101.                             break
  102.                         }
  103.                     }
  104.                 }
  105.             }
  106.         }
  107.         Open {
  108.             switch $item {
  109.                 Open {frontierOpen}
  110.                 Add {frontierAddPoint Open}
  111.                 Remove {frontierRemovePoint Open}
  112.                 default {
  113.                     foreach b $FronmodeVars(OpenPoints) {
  114.                         if {[lindex $b 0] == $item} {
  115.                             frontierDoScript "edit (@[lindex $b 1])" front
  116.                             break
  117.                         }
  118.                     }
  119.                 }
  120.             }
  121.         }
  122.     }
  123. }
  124.  
  125.  
  126. # Called by Frontier when opening a Frontier text document in Alpha.
  127. proc openFromFrontier {} {
  128.     global frontierWinList winModes
  129.     set name [lindex [winNames -f] 0]
  130.     set name0 [stripNameCount $name]
  131.     if {[lsearch -exact $frontierWinList $name0] < 0} {lappend frontierWinList $name0}
  132. }
  133.  
  134. # If the current document is a Frontier document, it is updated in Frontier.
  135. proc frontierSavePostHook {name} {
  136.     global frontierWinList
  137.     if {[lsearch -exact $frontierWinList $name] >= 0} {
  138.         launchBackAppl 'LAND'
  139.         AEBuild 'LAND' ALFA FMod "----" "“${name}”"
  140.     }
  141. }
  142.  
  143. # ◊◊◊◊ Change below for new system §15 ◊◊◊◊ #
  144.  
  145. # Adds the above proc to the list of procs to be called after a document is saved.
  146. if {![info exists savePostHooks] || [lsearch -exact $savePostHooks frontierSavePostHook] < 0} {
  147.     lappend savePostHooks frontierSavePostHook
  148. }
  149.  
  150. # ◊◊◊◊ end changing for new system §15 ◊◊◊◊ #
  151.  
  152. # A list of windows opened from Frontier.
  153. if {![info exists frontierWinList]} {set frontierWinList {}}
  154.  
  155. # Executes a script in Frontier.
  156. proc frontierDoScript {script {front 0} {alert 1}} {
  157.     launchBackAppl 'LAND'
  158.     if {[catch {dosc -c 'LAND' -s $script} returnvalue]} {
  159.         if {$alert} {
  160.             alertnote "Frontier $returnvalue"
  161.             error "Frontier $returnvalue"
  162.         }
  163.         error $returnvalue
  164.     } elseif {$front == "front"} {
  165.         switchTo 'LAND'
  166.     }
  167.     return $returnvalue
  168. }
  169.  
  170. # Executes one of the scripts in Frontier, which are required to use Alpha with Frontier.
  171. proc frontierDoAlphaScript {script} {
  172.     global HOME
  173.     if {[catch {frontierDoScript $script 0 0} res]} {
  174.         alertnote "The Frontier verbs required to integrate Alpha and Frontier have not been\
  175.             properly installed. See the file 'Frontier Help.'"
  176.         edit -r -c "$HOME:Help:Frontier Help"
  177.         error $res
  178.     }
  179.     return $res
  180. }
  181.  
  182. # ◊◊◊◊ Change below for new system §16 ◊◊◊◊ #
  183.  
  184. # Redefines closeHook
  185. if {[info commands frontierCloseHook] == ""} {
  186.     rename closeHook frontierCloseHook
  187.     # If the window to be closed is a Frontier document, it is removed
  188.     # from Frontier's list of open external documents.
  189.     proc closeHook {name} {
  190.         global frontierWinList frontierQSWin frontierCommandHistory frontierCommandNum
  191.         # First do the normal thing.
  192.         frontierCloseHook $name
  193.         # Then do the Frontier stuff.
  194.         if {[set where [lsearch -exact $frontierWinList $name]] >= 0} {
  195.             launchBackAppl 'LAND'
  196.             AEBuild 'LAND' ALFA FCls "----" "“${name}”"    
  197.             set frontierWinList [lreplace $frontierWinList $where $where]
  198.         }
  199.         if {$name == $frontierQSWin} {set frontierCommandHistory ""; set frontierCommandNum 0}
  200.     }
  201. }
  202.  
  203. # Redefines saveasHook
  204. if {[info commands frontierSaveasHook] == ""} {
  205.     rename saveasHook frontierSaveasHook
  206.     proc saveasHook {oldname newname} {
  207.         global frontierWinList
  208.         # First do the normal thing.
  209.         frontierSaveasHook $oldname $newname
  210.         # Modify the Frontier win list if it's a Frontier window.
  211.         # and notify Frontier about it.
  212.         if {[set where [lsearch -exact $frontierWinList $oldname]] >= 0} {
  213.             set frontierWinList [lreplace $frontierWinList $where $where $newname]
  214.             launchBackAppl 'LAND'
  215.             AEBuild 'LAND' ALFA FMod "----" "“${oldname}”" zzzz "“${newname}”"
  216.         }
  217.     }
  218. }
  219.  
  220. # ◊◊◊◊ end changing for new system §16 ◊◊◊◊ #
  221.  
  222. # Does the same as 'View in Browser' in Frontier's web menu.
  223. proc frontierViewinBrowser {} {
  224.     global frontierWinList
  225.     if {![llength [winNames]]} {
  226.         alertnote "No window!"
  227.         return
  228.     }
  229.     if {[lsearch $frontierWinList [set name [stripNameCount [lindex [winNames -f] 0]]]] >= 0} {
  230.         if {[winDirty]} {
  231.             if {[set ask [askyesno -c "Save '[file tail $name]'?"]] == "yes"} {
  232.                 save
  233.             } elseif {$ask == "cancel"} {
  234.                 return
  235.             }
  236.         }
  237.         frontierDoAlphaScript "Alpha.viewInBrowser(\"$name\")"
  238.     } else {
  239.         alertnote "Not a Frontier window."
  240.     }
  241. }
  242.  
  243. # Open a window in Frontier
  244. proc frontierOpen {} {
  245.     if {![catch {frontierGetAddress} addr]} {
  246.         frontierDoScript "edit (@$addr)" front
  247.     }
  248. }
  249.  
  250. # Browse a table in Frontier
  251. proc frontierBrowseAt {} {
  252.     if {![catch {frontierGetAddress} addr]} {
  253.         odbBrowse $addr
  254.     }
  255. }
  256.  
  257. # Add to Browse and Open submenus
  258. proc frontierAddPoint {type} {
  259.     global FronmodeVars modifiedModeVars
  260.     set values ""
  261.     while {1} {
  262.         set values [dialog -w 450 -h 130 -t "Add $type menu item" 30 10 290 30 \
  263.             -t "Location in database:" 10 40 160 60 -e [lindex $values 0] 165 40 440 55 \
  264.             -t "Menu text:" 78 70 160 90 -e [lindex $values 1] 165 70 440 85 \
  265.             -b OK 20 100 85 120 -b Cancel 105 100 170 120]
  266.         if {[lindex $values 3]} {return}
  267.         set addr [string trim [lindex $values 0]]
  268.         if {$addr == ""} {alertnote "Location is database must be specified."; continue}
  269.         set text [string trim [lindex $values 1]]
  270.         if {$text == ""} {alertnote "The menu item must be specified."; continue}
  271.         if {[frontierDoScript "defined($addr)"] == "true"} {
  272.             set ex 0
  273.             foreach b $FronmodeVars(${type}Points) {
  274.                 if {[lindex $b 0] == $text} {alertnote "A menu item '$text' already exists."; set ex 1}
  275.             }
  276.             if {!$ex} {break}
  277.         } else {
  278.             alertnote "“$addr” is not a valid database address."
  279.         }
  280.     }
  281.     lappend FronmodeVars(${type}Points) [list $text $addr]
  282.     lappend modifiedModeVars [list ${type}Points FronmodeVars]
  283.     eval [eval frontier${type}Menu]
  284. }
  285.  
  286. # Remove from Browse and Open submenus.
  287. proc frontierRemovePoint {type} {
  288.     global FronmodeVars modifiedModeVars
  289.     set points {}
  290.     foreach b $FronmodeVars(${type}Points) {
  291.         lappend points [lindex $b 0]
  292.         set pointat([lindex $b 0]) [lindex $b 1]
  293.     }
  294.     if {![llength $points] || [catch {listpick -p "Select [string tolower $type] point to remove:" -l $points} points] ||
  295.         ![llength $points]} {return}
  296.     set points [lindex $points 0]
  297.     if {[askyesno "'$points' points to '$pointat($points)'. Remove?"] != "yes"} {return}
  298.     set n {}
  299.     foreach b $FronmodeVars(${type}Points) {
  300.         if {[lindex $b 0] != $points} {lappend n $b}
  301.     }
  302.     set FronmodeVars(${type}Points) $n
  303.     lappend modifiedModeVars [list ${type}Points FronmodeVars]
  304.     eval [eval frontier${type}Menu]
  305. }
  306.  
  307. proc frontierGetAddress {} {
  308.     while {1} {
  309.         if {[catch {set addr [prompt "Location in Frontier database:" ""]}]} {
  310.             error ""
  311.         } else {
  312.             set addr [string trimleft [string trim $addr] {@}]
  313.             switch [frontierDoScript "defined($addr)"] {
  314.                 "true"        {return $addr}
  315.                 "false"        {alertnote "“$addr” is not a valid database address"}
  316.                 ""            {error ""}
  317.             }
  318.         }
  319.     }
  320. }
  321.  
  322. proc FronmodifyFlags {} {
  323.     global FronmodeVars modifiedModeVars
  324.     set values [dialog -w 300 -h 110 -t "Frontier Preferences" 30 10 290 30 \
  325.         -c "Launch Frontier at startup" $FronmodeVars(autoLaunch) 10 40 290 60 \
  326.         -b OK 20 80 85 100 -b Cancel 105 80 170 100]
  327.     if {[lindex $values 2]} {return}
  328.     set i -1
  329.     foreach flag [list autoLaunch] {
  330.         global $flag
  331.         incr i
  332.         set val [lindex $values $i]
  333.         if {$FronmodeVars($flag) != $val} {
  334.             set $flag $val
  335.             set FronmodeVars($flag) $val
  336.             lappend modifiedModeVars [list $flag FronmodeVars]
  337.         }
  338.     }
  339. }
  340.  
  341. proc OdbmodifyFlags {} {
  342.     FronmodifyFlags
  343. }
  344.  
  345. #===============================================================================
  346. # Script menu
  347. # The code to extract a Frontier menu has been written by
  348. # Danis Georgiadis <dmg@hyper.gr>
  349. #===============================================================================
  350.  
  351. proc setFrontierMenuScript {menu item scpt} {
  352.     global frontierMenuScripts
  353.     if {[regexp {&$} $item]} {
  354.         set item [string trimright $item &]
  355.     } else {
  356.         regsub -all {<[BUISEO]} $item "" item
  357.         regsub {/[a-zA-Z]} $item "" item
  358.         regsub -all {[!\^].} $item "" item
  359.     }
  360.     set key [string trimright "$menu$item" …]
  361.     set frontierMenuScripts($key) $scpt
  362. }
  363.  
  364. proc frontierBuildScriptMenu {} {
  365.     global frontierScriptMenu FronmodeVars
  366.  
  367.     set running 0
  368.     foreach    p [processes] {
  369.         if {[lindex $p 1] == "LAND" } {
  370.             set running 1
  371.         }
  372.     }
  373.     if {!$running} {
  374.         if {$FronmodeVars(autoLaunch)} {
  375.             launchBackAppl 'LAND'
  376.         } else {
  377.             return
  378.         }
  379.     }
  380.     set sfina [frontierDoAlphaScript "Alpha.getMenuSource()"]
  381.      set ptext [frontierDoAlphaScript "Alpha.getDefsSource()"]
  382.     
  383.     set mtext [list menu -m -n $frontierScriptMenu -p frontierScriptMenuProc $sfina]
  384.     eval $mtext
  385.     eval $ptext
  386.     
  387.     insertMenu $frontierScriptMenu
  388.  
  389. }
  390.  
  391. proc frontierScriptMenuProc {menu item} {
  392.     global frontierMenuScripts frontierScriptMenu
  393.     if {$menu == $frontierScriptMenu} {set menu ""}
  394.     set key "$menu$item"
  395.     frontierDoScript $frontierMenuScripts($key)
  396. }
  397.  
  398. proc frontierRebuildScriptsMenu {} {
  399.     global frontierMenuScripts
  400.     launchBackAppl 'LAND'
  401.     frontierDoAlphaScript "Alpha.invalMenuSources()"
  402.     catch {unset frontierMenuScripts}
  403.     frontierBuildScriptMenu
  404. }
  405.  
  406.  
  407. #===============================================================================
  408. #
  409. # Frontier shell
  410. # Some ideas taken from Matlab mode by Stephen Merkowitz
  411. #===============================================================================
  412. set frontierQSWin "* Frontier shell *"
  413. set frontierCommandHistory ""
  414. set frontierCommandNum 0
  415.  
  416. proc frontierFrontierShell {} {
  417.     global frontierQSWin
  418.     
  419.     if {[lsearch [winNames] $frontierQSWin] >= 0} {
  420.         bringToFront $frontierQSWin
  421.     } else {
  422.         new -n $frontierQSWin
  423.         setWinInfo -w $frontierQSWin shell 1
  424.         
  425.         newMode Fron
  426.         insertText "Welcome to Alpha's Frontier shell\r«» "
  427.     }
  428. }
  429.  
  430.  
  431. proc frontierRunQuickScript {} {
  432.     global frontierCommandHistory frontierCommandNum frontierQSWin
  433.     set pos [getPos]
  434.  
  435.     set ind [string first "«» " [getText [lineStart $pos] [nextLineStart [getPos]]]]
  436.     if {$ind >= 0} {
  437.         set lStart [expr [lineStart $pos]+$ind+2]
  438.         endOfLine
  439.         set scriptName [getText $lStart [getPos]]
  440.         if {[getPos] != [maxPos]} {
  441.             goto [maxPos]
  442.             insertText $scriptName
  443.         }
  444.         
  445.         catch {frontierDoScript $scriptName 0 0} result
  446.         if {[string compare [lindex $frontierCommandHistory [expr [llength $frontierCommandHistory]-1]] $scriptName] != 0} {
  447.             lappend frontierCommandHistory $scriptName
  448.             if {[llength $frontierCommandHistory] > 30} {
  449.                 set frontierCommandHistory [lrange $frontierCommandHistory 1 end]
  450.             }
  451.         }
  452.         set frontierCommandNum [llength $frontierCommandHistory]
  453.         if {[string length $result]} {
  454.             insertText -w $frontierQSWin "\r" $result \r "«» "
  455.         } else {
  456.             insertText -w $frontierQSWin \r "«» "
  457.         }
  458.     } else {
  459.            if {[getPos] == [maxPos]} {
  460.             insertText "«» "
  461.         } else {
  462.             carriageReturn
  463.         }
  464.     }
  465.     return
  466. }
  467.  
  468.  
  469. proc frontierPrevCommand {} {
  470.     global frontierCommandHistory frontierCommandNum
  471.     
  472.     set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
  473.     if {[set ind [string first "«» " $text]] == 0} {
  474.         goto [expr [lineStart [getPos]] + $ind + 2]
  475.     } else return
  476.  
  477.     incr frontierCommandNum -1
  478.     if {$frontierCommandNum < 0} {
  479.         incr frontierCommandNum
  480.         endOfLine
  481.         return
  482.     }
  483.     set text [lindex $frontierCommandHistory $frontierCommandNum]
  484.     set to [nextLineStart [getPos]]
  485.     if {[lookAt [expr $to-1]] == "\r"} {incr to -1}
  486.     replaceText [getPos] $to $text
  487. }
  488.  
  489.  
  490. proc frontierNextCommand {} {
  491.     global frontierCommandHistory frontierCommandNum
  492.     
  493.     set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
  494.     if {[set ind [string first "«» " $text]] == 0} {
  495.         goto [expr [lineStart [getPos]] + $ind + 2]
  496.     } else return
  497.  
  498.     incr frontierCommandNum
  499.     if {$frontierCommandNum >= [llength $frontierCommandHistory]} {
  500.         incr frontierCommandNum -1
  501.         frontierCancelLine
  502.         return
  503.     }
  504.     set text [lindex $frontierCommandHistory $frontierCommandNum]
  505.     set to [nextLineStart [getPos]]
  506.     if {[lookAt [expr $to-1]] == "\r"} {incr to -1}
  507.     replaceText [getPos] $to $text
  508. }
  509.  
  510. proc frontierCancelLine {} {
  511.     global frontierCommandHistory frontierCommandNum
  512.  
  513.     set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
  514.     if {[set ind [string first "«» " $text]] == 0} {
  515.         goto [expr [lineStart [getPos]] + $ind + 3]
  516.     } else return
  517.     
  518.     set to [nextLineStart [getPos]]
  519.     deleteText [getPos] $to
  520.     
  521.     set frontierCommandNum [llength $frontierCommandHistory]
  522. }
  523.  
  524. proc frontierBol {} {
  525.     set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
  526.     if {[set ind [string first "«» " $text]] == 0} {
  527.         goto [expr [lineStart [getPos]] + $ind + 3]
  528.     } else {
  529.         goto [lineStart [getPos]]
  530.     }
  531. }
  532.  
  533.  
  534. regModeKeywords -m {«} Fron {}
  535. bind up <z> frontierPrevCommand Fron
  536. bind down <z> frontierNextCommand Fron
  537. bind '\r' frontierRunQuickScript Fron
  538. bind 'u'  <z>  frontierCancelLine  Fron
  539. bind left <c> frontierBol Fron
  540.  
  541. #===============================================================================
  542. # Odb browser
  543. # Written by Danis Georgiadis <dmg@hyper.gr> and modified by me to be integrated 
  544. # with the rest.
  545. #===============================================================================
  546.  
  547. set odbBrowserTabLength 3
  548. set odbBrowserTypeOffset 60
  549.  
  550. proc odbget120Spaces {} {
  551.     set spaces40 "                                        "
  552.     return "$spaces40$spaces40$spaces40"
  553. }
  554.  
  555. proc odbGetIndLevel {indStr} {
  556.     global odbBrowserTabLength
  557.     return [expr [string length $indStr] / $odbBrowserTabLength]
  558. }
  559.  
  560. proc odbGetIndString {indLevel} {
  561.     global odbBrowserTabLength
  562.     return [string range [odbget120Spaces] 0 [expr [expr $indLevel * $odbBrowserTabLength] - 1]]
  563. }
  564.  
  565. proc odbGetNextIndString {thisIndStr} {
  566.     return [odbGetIndString [expr [odbGetIndLevel $thisIndStr] + 1]]
  567. }
  568.  
  569. proc odbBrowseGetLineParts {name type addr level} {
  570.     global odbBrowserTypeOffset
  571.     global odbBrowserTabLength
  572.     
  573.     set indPadPart [odbGetIndString $level]
  574.     set namePart [string trim $name "\t "]
  575.     set typePadSize [expr $odbBrowserTypeOffset - [expr [string length $indPadPart] + [string length $name]]]
  576.     set typePadPart [string range [odbget120Spaces] 0 [expr $typePadSize - 1]]
  577.     set typePart "◊$type◊"
  578.     set addrPart "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t∞$addr∞"
  579.     
  580.     set res ""
  581.     lappend res $indPadPart $namePart $typePadPart $typePart $addrPart
  582.     
  583.     return $res
  584. }
  585.  
  586. proc odbBrowseDown {} {
  587.     set curPos [getPos]
  588.     set curLineStart [lineStart $curPos]
  589.     set curLineEnd [nextLineStart $curPos]
  590.     select $curLineStart $curLineEnd
  591.     
  592.     set newLineStart [nextLineStart $curLineStart]
  593.     set newLineEnd [nextLineStart $newLineStart]
  594.     if {$newLineStart < [maxPos]} {
  595.         select $newLineStart $newLineEnd
  596.     }
  597. }
  598.  
  599. proc odbBrowseCmdDown {{option 0}} {
  600.     set curPos [getPos]
  601.     set curLineStart [lineStart $curPos]
  602.     set curLineEnd [nextLineStart $curPos]
  603.     
  604.     if {[regexp {^( *).+◊tabl◊\t+∞(.+)∞} [getText $curLineStart $curLineEnd] junk ind addr]} {
  605.         if {$option} {killWindow}
  606.         odbBrowse $addr
  607.     }
  608. }
  609.  
  610. proc odbBrowseUp {} {
  611.     set curPos [getPos]
  612.     set curLineStart [lineStart $curPos]
  613.     set curLineEnd [nextLineStart $curPos]
  614.     select $curLineStart $curLineEnd
  615.     
  616.     set newLineStart [prevLineStart $curLineStart]
  617.     set newLineEnd [nextLineStart $newLineStart]
  618.     if {$newLineEnd > 0} {
  619.         select $newLineStart $newLineEnd
  620.     }
  621. }
  622.  
  623. proc odbBrowseCmdUp {{option 0}} {
  624.     regexp {∞(.+)∞} [getText 0 [nextLineStart 0]] junk addr
  625.     if {[set point [string last "." $addr]] >= 0} {
  626.         if {$option} {killWindow}
  627.         odbBrowse [string range $addr 0 [expr $point - 1]]
  628.     }
  629. }
  630.  
  631. proc odbBrowserAddCells {pos cells indLevel} {
  632.     
  633.     set tmp ""
  634.     set colorCodes ""
  635.     set lastPos $pos
  636.     
  637.     foreach cell $cells {
  638.         set cellName [lindex $cell 0]
  639.         set cellType [lindex $cell 1]
  640.         set cellAddr [lindex $cell 2]
  641.         
  642.         set parts [odbBrowseGetLineParts $cellName $cellType $cellAddr $indLevel]
  643.         
  644.         set indPart [lindex $parts 0]
  645.         set namePart [lindex $parts 1]
  646.         set typePartPad [lindex $parts 2]
  647.         set typePart [lindex $parts 3]
  648.         set addrPart [lindex $parts 4]
  649.         
  650.         set nameStart [expr $lastPos + [string length $indPart]]
  651.         set nameEnd [expr $nameStart + [string length $namePart]]
  652.         
  653.         if {$cellType == "TEXT" || $cellType == "wptx"} {
  654.             lappend colorCodes [concat $nameStart 3]
  655.             lappend colorCodes [concat $nameEnd 0]
  656.         } elseif {$cellType == "tabl"} {
  657.             lappend colorCodes [concat $nameStart 5]
  658.             lappend colorCodes [concat $nameEnd 0]
  659.         } else {
  660.             lappend colorCodes [concat $nameStart 1]
  661.             lappend colorCodes [concat $nameEnd 0]
  662.         }
  663.         
  664.         set typeStart [expr $lastPos + [string length $indPart] + [string length $namePart] + [string length $typePartPad]]
  665.         set typeEnd [expr $typeStart + [string length $typePart]]
  666.         lappend colorCodes [concat $typeStart 4]
  667.         lappend colorCodes [concat $typeEnd 0]
  668.         
  669.         set line ""
  670.         append line $indPart $namePart $typePartPad $typePart $addrPart "\n"
  671.         append tmp $line
  672.         
  673.         set lastPos [expr $lastPos + [string length $line]]
  674.     }
  675.     
  676.     select $pos $pos
  677.     setWinInfo read-only 0
  678.     
  679.     insertText $tmp
  680.     
  681.     foreach colorCode $colorCodes {
  682.         insertColorEscape [lindex $colorCode 0] [lindex $colorCode 1]
  683.     }
  684.     
  685.     setWinInfo dirty 0
  686.     setWinInfo read-only 1
  687.     eval sizeWin [lrange [getGeometry] 2 end]
  688. }
  689.  
  690. proc odbBrowseRight {} {
  691.     set curPos [getPos]
  692.     set curLineStart [lineStart $curPos]
  693.     set curLineEnd [nextLineStart $curPos]
  694.     
  695.     if {[regexp {^( *).+◊tabl◊\t+∞(.+)∞} [getText $curLineStart $curLineEnd] junk ind addr]} {
  696.         set nextIndString [odbGetNextIndString $ind]
  697.         set nextLineText [getText [nextLineStart $curLineStart] [nextLineStart [nextLineStart $curLineStart]]]
  698.         if {![regexp "^$nextIndString" $nextLineText junk]} {
  699.             
  700.             set cells [frontierDoAlphaScript "Alpha.getCellData(@$addr)"]
  701.             odbBrowserAddCells $curLineEnd $cells [odbGetIndLevel $nextIndString]
  702.             
  703.         }
  704.     }
  705.     
  706.     select $curLineStart $curLineEnd
  707. }
  708.  
  709. proc odbBrowseLeft {} {
  710.     set curPos [getPos]
  711.     set curLineStart [lineStart $curPos]
  712.     set curLineEnd [nextLineStart $curPos]
  713.     
  714.     if {[regexp {^( *).+∞(.+)∞} [getText $curLineStart $curLineEnd] junk ind elems]} {
  715.         set pos [nextLineStart $curLineStart]
  716.         set start $pos
  717.         set nextIndString [odbGetNextIndString $ind]
  718.         while {[regexp "^$nextIndString" [getText $pos [nextLineStart $pos]] junk]} {
  719.             set pos [nextLineStart $pos]
  720.         }
  721.         setWinInfo read-only 0
  722.         deleteText $start $pos
  723.         setWinInfo dirty 0
  724.         setWinInfo read-only 1
  725.     }
  726.     select $curLineStart $curLineEnd
  727. }
  728.  
  729. proc odbBrowseEditObj {} {
  730.     set curPos [getPos]
  731.     set curLineStart [lineStart $curPos]
  732.     set curLineEnd [nextLineStart $curPos]
  733.     
  734.     if {[regexp {^.+∞(.+)∞} [getText $curLineStart $curLineEnd] junk addr]} {
  735.         frontierDoAlphaScript "Alpha.editCell(@$addr)"
  736.     }
  737. }
  738.  
  739. proc odbBrowse {{addr root}} {
  740.     if {$addr == ""} {
  741.         return
  742.     }
  743.     
  744.     global odbBrowserTypeOffset
  745.     global odbBrowserTabLength
  746.     
  747.     set cell [frontierDoAlphaScript "Alpha.getCellData(@$addr, false)"]
  748.     set wtitle "* Frontier “[lindex [lindex $cell 0] 2]” *"
  749.     
  750.     if {[lsearch [winNames] $wtitle] >= 0} {
  751.         bringToFront $wtitle
  752.     } else {
  753.         new -n $wtitle -g 4 42 449 300
  754.         setWinInfo dirty 0
  755.         newMode Odb
  756.         odbBrowserAddCells 0 $cell 0
  757.         select 0 [nextLineStart 0]
  758.         odbBrowseRight
  759.     }
  760. }
  761.  
  762. bind '\r'        odbBrowseEditObj    Odb
  763. bind enter        odbBrowseEditObj    Odb
  764.  
  765. bind down         odbBrowseDown        Odb
  766. bind down <c>    odbBrowseCmdDown    Odb
  767. bind down <co>    {odbBrowseCmdDown 1}    Odb
  768. bind up            odbBrowseUp            Odb
  769. bind up <c>        odbBrowseCmdUp        Odb
  770. bind up <co>    {odbBrowseCmdUp 1}        Odb
  771. bind right        odbBrowseRight        Odb
  772. bind left        odbBrowseLeft        Odb
  773.  
  774. catch {frontierBuildScriptMenu}
  775.